Symbol data-block has the following format:
------------------------------------------------------- | 7 (data-block words) | Symbol Type (8 bits) | ------------------------------------------------------- | Value Descriptor | ------------------------------------------------------- | Function Pointer | ------------------------------------------------------- | Raw Function Address | ------------------------------------------------------- | Setf Function | ------------------------------------------------------- | Property List | ------------------------------------------------------- | Print Name | ------------------------------------------------------- | Package | -------------------------------------------------------
Most of these slots are self-explanatory given what symbols must do in Common Lisp, but a couple require comments. We added the Raw Function Address slot to speed up named call which is the most common calling convention. This is a non-descriptor slot, but since objects are dual word aligned, the value inherently has fixnum low-tag bits. The GC method for symbols must know to update this slot. The Setf Function slot is currently unused, but we had an extra slot due to adding Raw Function Address since objects must be dual-word aligned.
The issues with nil are that we want it to act like a symbol, and we need list operations such as CAR and CDR to be fast on it. CMU Common Lisp solves this by putting nil as the first object in static space, where other global values reside, so it has a known address in the system:
------------------------------------------------------- <-- space | 0 | start ------------------------------------------------------- | 7 (data-block words) | Symbol Type (8 bits) | ------------------------------------------------------- <-- nil | Value/CAR | ------------------------------------------------------- | Definition/CDR | ------------------------------------------------------- | Raw Function Address | ------------------------------------------------------- | Setf Function | ------------------------------------------------------- | Property List | ------------------------------------------------------- | Print Name | ------------------------------------------------------- | Package | ------------------------------------------------------- | ... | -------------------------------------------------------In addition, we make the list typed pointer to nil actually point past the header word of the nil symbol data-block. This has usefulness explained below. The value and definition of nil are nil. Therefore, any reference to nil used as a list has quick list type checking, and CAR and CDR can go right through the first and second words as if nil were a cons object.
When there is a reference to nil used as a symbol, the system adds offsets to the address the same as it does for any symbol. This works due to a combination of nil pointing past the symbol header-word and the chosen list and other-pointer type tags. The list type tag is four less than the other-pointer type tag, but nil points four additional bytes into its symbol data-block.
;;;; Array Headers.
The array-header data-block has the following format:
---------------------------------------------------------------- | Header Len (24 bits) = Array Rank +5 | Array Type (8 bits) | ---------------------------------------------------------------- | Fill Pointer (30 bits) | 0 0 | ---------------------------------------------------------------- | Available Elements (30 bits) | 0 0 | ---------------------------------------------------------------- | Data Vector (29 bits) | 1 1 1 | ---------------------------------------------------------------- | Displacement (30 bits) | 0 0 | ---------------------------------------------------------------- | Displacedp (29 bits) -- t or nil | 1 1 1 | ---------------------------------------------------------------- | Range of First Index (30 bits) | 0 0 | ---------------------------------------------------------------- . . .The array type in the header-word is one of the eight-bit patterns from section "Data-Blocks and Other-immediates Typing", indicating that this is a complex string, complex vector, complex bit-vector, or a multi-dimensional array. The data portion of the other-immediate word is the length of the array header data-block. Due to its format, its length is always five greater than the array's number of dimensions. The following words have the following interpretations and types: